package com.aiolos.mp.configuration;

import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * MP的配置类
 */
@Configuration
public class MybatisPulsConfig {

    /**
     * 配置MP分页插件
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        //调用多租户SQL解析器
        return myTenantSqlParser(paginationInterceptor);
        //return paginationInterceptor;
    }

    /**
     * 配置乐观锁插件
     * @return
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }

    /**
     * 实现多租户SQL解析器
     * @param paginationInterceptor
     */
    private PaginationInterceptor myTenantSqlParser(PaginationInterceptor paginationInterceptor){
        //1. 创建泛型为ISqlParser的List，ISqlParser就是SQL解析器接口
        List<ISqlParser> sqlParserList = new ArrayList<>();
        //2. 创建租户SQL解析器
        TenantSqlParser tenantSqlParser = new TenantSqlParser();
        //3. 设置TenantHandler
        tenantSqlParser.setTenantHandler(new TenantHandler() {
            @Override
            public Expression getTenantId(boolean where) {
                //传入的租户manager_id信息。一般从session中获取,这里固定写成某租户的id
                return new LongValue(2L);
            }

            @Override
            public String getTenantIdColumn() {
                //数据表中的多租户字段名
                return "manager_id";
            }

            @Override
            public boolean doTableFilter(String tableName) {
                //过滤哪些表不添加租户信息，false表示加租户信息；true表示不加租户信息
                if("role".equals(tableName)){
                    //角色表不加租户信息
                    return true;
                }
                return false;
            }
        });

        //4. 添加租户SQL解析器到SQL解析器列表中
        sqlParserList.add(tenantSqlParser);

        //5. 设置SQL解析器列表到分页插件中
        paginationInterceptor.setSqlParserList(sqlParserList);

        //特定SQL过滤方式一
//        paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
//            @Override
//            public boolean doFilter(MetaObject metaObject) {
//                //false表示增加租户信息；true表示不增加租户信息
//                MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
//
//                //方法名的全限定名称
//                if("com.aiolos.mp.dao.UserMapper.selectById".equals(ms.getId())){
//                    return true;
//                }
//
//                return false;
//            }
//        });
        return paginationInterceptor;
    }
}
